package com.macbulldev.poc.testgin.controller;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.macbulldev.poc.testgin.domain.PolicyForm;
import com.macbulldev.poc.testgin.domain.Rate;
import com.macbulldev.poc.testgin.domain.Scenario;
import com.macbulldev.poc.testgin.domain.TransactionQuestion;
import com.macbulldev.poc.testgin.domain.TrialCase;
import com.macbulldev.poc.testgin.domain.TrialGroup;
import com.macbulldev.poc.testgin.domain.Underwriter;


@org.springframework.roo.addon.web.mvc.controller.RooWebScaffold(path = "trialgroup", automaticallyMaintainView = false, formBackingObject = com.macbulldev.poc.testgin.domain.TrialGroup.class)
@org.springframework.web.bind.annotation.RequestMapping("/trialgroup/**")
@org.springframework.stereotype.Controller
public class TrialGroupController {
	
	private static final Logger LOGGER = Logger.getLogger(TrialGroupController.class);
	
	
	@RequestMapping(value = "/trialgroup/ajax/add_manual_group", method = RequestMethod.POST)    
    public String processGroupAdd(@RequestParam(value="visibility", required=false) String visibility,
    		@RequestParam(value="calcSteps", required=false) String calcSteps,
    		@RequestParam(value="testCaseName", required=false) String testCaseName,
    		@RequestParam(value="underwriter", required=false) Long uwId,
    		@RequestParam(value="scenarioId", required=false) Long scenarioId,
    		@RequestParam(value="cnt", required=false) Long cnt,
    		@RequestParam(value="policyEffectiveDate", required=false) String policyEffectiveDate,
    		ModelMap modelMap){
    	
		
		
		DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
		Date ped = null;
		try
		{
			ped = df.parse(policyEffectiveDate);           
		
		} catch (Exception e)
		{
			e.printStackTrace();
		}

		TrialGroup tg = new TrialGroup();
		tg.setVisibility(visibility);
		tg.setPolicyEffectiveDate(ped);
		tg.setScenario(Scenario.findScenario(scenarioId));
		tg.persist();
		
		Underwriter uw = new Underwriter();
		uw.setDisplayName(Underwriter.findUnderwriter(uwId).getDisplayName());
		uw.setImportName(Underwriter.findUnderwriter(uwId).getImportName());
		uw.setTrialGroup(tg);
		
		uw.persist();
		/*
		String tcName = "TC_"+Scenario.findScenario(scenarioId).getStateOrProvince().getCode();
		tcName = tcName+"_"+uw.getImportName()+"_"+tg.getVisibility()+"_"+tg.getScenario().getPolicyType().getAbbrName();
		tcName = tcName+"_"+tg.getScenario().getName();
		tcName = tcName+"_"+cnt;
		*/
		
		
		TrialCase tc = new TrialCase();
		tc.setCalcSteps(calcSteps);
		tc.setName(testCaseName);
		tc.setTrialGroup(tg);
		tc.persist();
		
		LOGGER.debug(visibility+"   >>>>>>>>   "+scenarioId+">>>>>  "+ped+"   >>>>>  "+uwId);
		
		modelMap.addAttribute("msg", tg.getId());  
		return "trialgroup/ajax_success"; 	
	}
	
	@RequestMapping(value = "/trialgroup/ajax/add_group", method = RequestMethod.POST)    
    public String processScenarioAdd(@RequestParam(value="visibility", required=false) String visibility,
    		@RequestParam(value="policyEffectiveDate", required=false) String policyEffectiveDate,
    		@RequestParam(value="minimum", required=false) BigDecimal minimum,
    		@RequestParam(value="liabilityRoundAmt", required=false) Long liabilityRoundAmt,
    		@RequestParam(value="basicRate", required=false) BigDecimal basicRate,
    		@RequestParam(value="additionalCharge", required=false) BigDecimal additionalCharge,
    		@RequestParam(value="rate", required=false) Long rate,
    		@RequestParam(value="underwriters", required=false) Long[] uwIds,
    		@RequestParam(value="scenario_id", required=false) Long scenarioId,
    		@RequestParam(value="roundingRule", required=false) String roundingRule,
    		@RequestParam(value="transactionQuestions", required=false) String transactionQuestions,
    		@RequestParam(value="reissueRate", required=false) BigDecimal reissueRate,
    		@RequestParam(value="policyForms", required=false) Long[] pfIds,
    		ModelMap modelMap,
    		HttpSession session) {        

		String retMsg = "1";
		
		DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
		Date ped = null;
		
		try
		{
			ped = df.parse(policyEffectiveDate);           
		
		} catch (Exception e)
		{
			e.printStackTrace();
		}
		
		
		TrialGroup tg = new TrialGroup();
		tg.setVisibility(visibility);
		tg.setPolicyEffectiveDate(ped);
		tg.setMinimum(minimum);
		tg.setLiabilityRoundAmt(liabilityRoundAmt);
		tg.setBasicRate(basicRate);
		tg.setAdditionalCharge(additionalCharge);
		tg.setRate(Rate.findRate(rate));
		tg.setScenario(Scenario.findScenario(scenarioId));
		tg.setRoundingRule(roundingRule);
		tg.setReissueRate(reissueRate);
	
		tg.persist();
		
		//Add Underwriters
		
		List<Underwriter> uwList = new ArrayList<Underwriter>();

		for(Long id : uwIds)
		{
			uwList.add(Underwriter.findUnderwriter(id));
		}
		
		for(Underwriter uw: uwList)
		{
			
			Underwriter underwriter = new Underwriter();
			underwriter.setDisplayName(uw.getDisplayName());
			underwriter.setImportName(uw.getImportName());
			underwriter.setCreateUsername(null);
			underwriter.setUpdateUsername(null);
			underwriter.setTrialGroup(tg);
			underwriter.persist();
			
		}
		
		//Add Policy Forms
		
		List<PolicyForm> pfList = new ArrayList<PolicyForm>();
		LOGGER.error("policy form size:  "+pfIds.length);
		for(Long id : pfIds)
		{
			LOGGER.error("Adding Group, adding policy form to group:  "+PolicyForm.findPolicyForm(id));
			pfList.add(PolicyForm.findPolicyForm(id));
		}
		
		for(PolicyForm pf: pfList)
		{
			
			PolicyForm policyForm = new PolicyForm();
			policyForm.setDisplayName(pf.getDisplayName());
			policyForm.setImportName(pf.getImportName());
			policyForm.setAbbrName(pf.getAbbrName());
			policyForm.setCreateUsername(null);
			policyForm.setUpdateUsername(null);
			policyForm.setTrialGroup(tg);
			policyForm.persist();
			
		}
		
		//Add Transaction Questions
		
		String[] tqArr = transactionQuestions.split(",");
		
		for(String tq : tqArr)
		{
			if(tq.trim().length() > 0)
			{
				
				/* need to fix this to include type */
				
				String id = tq.split(":")[0];
				String a = tq.split(":")[1];
				String type = tq.split(":")[2];
				
				String q = TransactionQuestion.findTransactionQuestion(Long.parseLong(id)).getQuestion();
				
				TransactionQuestion newTq = new TransactionQuestion();
				newTq.setQuestion(q);
				newTq.setAnswer(a);
				newTq.setType(type);
				newTq.setTrialGroup(tg);
				newTq.persist();
			}
		}
		
		//Generate Test Cases Here
		
		
		
		modelMap.addAttribute("msg", retMsg);  
		return "trialgroup/ajax_success"; 
	}
	@Transactional
	@RequestMapping(value = "/trialgroup/ajax/delete_groups/{id}", method = RequestMethod.POST)      
    public String deleteTrialGroups(@PathVariable("id") Long scenarioId,ModelMap modelMap,HttpSession session) 
	{
		
		Scenario s = Scenario.findScenario(scenarioId);
		List<TrialGroup> tgList = TrialGroup.findTrialGroupsByScenario(scenarioId);
		
		LOGGER.error("Deleteing groups for scenario:  "+scenarioId);
		
		for(TrialGroup tg: tgList)
		{
			List<Underwriter> uwList = Underwriter.findUnderwriterByGroup(tg.getId());
			for(Underwriter uw: uwList)
			{
				uw.remove();
			}
			Set<PolicyForm> pfList = tg.getPolicyForms();
			for(PolicyForm pf: pfList)
			{
				pf.remove();
			}
			tg.remove();
		}
		modelMap.addAttribute("msg","1");
		return "trialgroup/ajax_success";
	}
	

	@RequestMapping(value = "/trialgroup", method = RequestMethod.POST)    
    public String create(@Valid TrialGroup trialGroup, BindingResult result, ModelMap modelMap) {    
        if (trialGroup == null) throw new IllegalArgumentException("A trialGroup is required");        
        if (result.hasErrors()) {        
            modelMap.addAttribute("trialGroup", trialGroup);            
            modelMap.addAttribute("rates", Rate.findAllRates());            
            modelMap.addAttribute("scenarios", Scenario.findAllScenarios());            
            modelMap.addAttribute("trialcases", TrialCase.findAllTrialCases());            
            modelMap.addAttribute("underwriters", Underwriter.findAllUnderwriters());            
            modelMap.addAttribute("trialGroup_policyEffectiveDate_date_format", org.joda.time.format.DateTimeFormat.patternForStyle("S-", org.springframework.context.i18n.LocaleContextHolder.getLocale()));            
            return "trialgroup/create";            
        }        
        trialGroup.persist();        
        return "redirect:/trialgroup/" + trialGroup.getId();        
    }

	@RequestMapping(value = "/trialgroup/form", method = RequestMethod.GET)    
    public String createForm(ModelMap modelMap) {    
        modelMap.addAttribute("trialGroup", new TrialGroup());        
        modelMap.addAttribute("rates", Rate.findAllRates());        
        modelMap.addAttribute("scenarios", Scenario.findAllScenarios());        
        modelMap.addAttribute("trialcases", TrialCase.findAllTrialCases());        
        modelMap.addAttribute("underwriters", Underwriter.findAllUnderwriters());        
        modelMap.addAttribute("trialGroup_policyEffectiveDate_date_format", org.joda.time.format.DateTimeFormat.patternForStyle("S-", org.springframework.context.i18n.LocaleContextHolder.getLocale()));        
        return "trialgroup/create";        
    }

	@RequestMapping(value = "/trialgroup/{id}", method = RequestMethod.GET)    
    public String show(@PathVariable("id") Long id, ModelMap modelMap) {    
        if (id == null) throw new IllegalArgumentException("An Identifier is required");        
        modelMap.addAttribute("trialGroup_policyEffectiveDate_date_format", org.joda.time.format.DateTimeFormat.patternForStyle("S-", org.springframework.context.i18n.LocaleContextHolder.getLocale()));        
        modelMap.addAttribute("trialGroup", TrialGroup.findTrialGroup(id));        
        return "trialgroup/show";        
    }

	@RequestMapping(value = "/trialgroup", method = RequestMethod.GET)    
    public String list(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, ModelMap modelMap) {    
        if (page != null || size != null) {        
            int sizeNo = size == null ? 10 : size.intValue();            
            modelMap.addAttribute("trialgroups", TrialGroup.findTrialGroupEntries(page == null ? 0 : (page.intValue() - 1) * sizeNo, sizeNo));            
            float nrOfPages = (float) TrialGroup.countTrialGroups() / sizeNo;            
            modelMap.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));            
        } else {        
            modelMap.addAttribute("trialgroups", TrialGroup.findAllTrialGroups());            
        }        
        modelMap.addAttribute("trialGroup_policyEffectiveDate_date_format", org.joda.time.format.DateTimeFormat.patternForStyle("S-", org.springframework.context.i18n.LocaleContextHolder.getLocale()));        
        return "trialgroup/list";        
    }

	@RequestMapping(method = RequestMethod.PUT)    
    public String update(@Valid TrialGroup trialGroup, BindingResult result, ModelMap modelMap) {    
        if (trialGroup == null) throw new IllegalArgumentException("A trialGroup is required");        
        if (result.hasErrors()) {        
            modelMap.addAttribute("trialGroup", trialGroup);            
            modelMap.addAttribute("rates", Rate.findAllRates());            
            modelMap.addAttribute("scenarios", Scenario.findAllScenarios());            
            modelMap.addAttribute("trialcases", TrialCase.findAllTrialCases());            
            modelMap.addAttribute("underwriters", Underwriter.findAllUnderwriters());            
            modelMap.addAttribute("trialGroup_policyEffectiveDate_date_format", org.joda.time.format.DateTimeFormat.patternForStyle("S-", org.springframework.context.i18n.LocaleContextHolder.getLocale()));            
            return "trialgroup/update";            
        }        
        trialGroup.merge();        
        return "redirect:/trialgroup/" + trialGroup.getId();        
    }

	@RequestMapping(value = "/trialgroup/{id}/form", method = RequestMethod.GET)    
    public String updateForm(@PathVariable("id") Long id, ModelMap modelMap) {    
        if (id == null) throw new IllegalArgumentException("An Identifier is required");        
        modelMap.addAttribute("trialGroup", TrialGroup.findTrialGroup(id));        
        modelMap.addAttribute("rates", Rate.findAllRates());        
        modelMap.addAttribute("scenarios", Scenario.findAllScenarios());        
        modelMap.addAttribute("trialcases", TrialCase.findAllTrialCases());        
        modelMap.addAttribute("underwriters", Underwriter.findAllUnderwriters());        
        modelMap.addAttribute("trialGroup_policyEffectiveDate_date_format", org.joda.time.format.DateTimeFormat.patternForStyle("S-", org.springframework.context.i18n.LocaleContextHolder.getLocale()));        
        return "trialgroup/update";        
    }

	@RequestMapping(value = "/trialgroup/{id}", method = RequestMethod.DELETE)    
    public String delete(@PathVariable("id") Long id, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size) {    
        if (id == null) throw new IllegalArgumentException("An Identifier is required");        
        TrialGroup.findTrialGroup(id).remove();        
        return "redirect:/trialgroup?page=" + ((page == null) ? "1" : page.toString()) + "&size=" + ((size == null) ? "10" : size.toString());        
    }
}
